package com.lottery.obtainData;

import com.lottery.dao.qiuqiu.accoutDao.UserDao;
import com.lottery.dao.qiuqiu.lobbyDao.LotteryDao;
import com.lottery.dao.qiuqiu.lobbyDao.WinningResultsDao;
import com.lottery.dao.qiuqiu.wealthDao.AccountDao;
import com.lottery.dto.*;
import com.lottery.entity.Account;
import com.lottery.entity.Lottery;
import com.lottery.entity.LotteryExchange;
import com.lottery.entity.User;
import com.lottery.service.qiuqiu.JedisClient;
import com.lottery.service.qiuqiu.MsgService.MsgNoticeService;
import com.lottery.service.qiuqiu.lobbyService.LotteryDrawService;
import com.lottery.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.*;
import java.util.Map.Entry;

@Component
public class Pc28AchieveData {
	/*@Autowired
	private LotteryDao lotteryDao;
	@Autowired
	private LotteryDrawService lotteryDrawService;
	@Autowired
	private JedisClient jedisClient;
	@Autowired
	private MsgNoticeService msgNoticeService;
	@Autowired
	private WinningResultsDao winningResultsDao;
	@Autowired
	private AccountDao accountDao;
	@Autowired
	private UserDao userDao;

	private MessageTubes messageTubes = MessageTubes.getInstance();

	// 中奖信息标志key
	@Value("${PC28FLG}")
	private String FLG;
	// 当前开奖的期号
	@Value("${PC28EXPECT}")
	private String EXPECT;
	// 当前开奖的号码
	@Value("${PC28OPENCODE}")
	private String OPENCODE;
	// 当前开奖的时间
	@Value("${PC28OPENDATE}")
	private String OPENDATE;
	// 下一次开奖的时间
	@Value("${PC28NEXTTIME}")
	private String NEXTTIME;
	// 下一次开奖的期号
	@Value("${PC28NEXTEXPECT}")
	private String NEXTEXPECT;
	// 停止下注
	@Value("${STOPBET}")
	private String STOPBET;
	// 停止下注
	@Value("${PC28LOTTERYINTERFACE}")
	private String PC28LOTTERYINTERFACE;
	// 开始下注
	@Value("${BEGAINBET}")
	private String BEGAINBET;
	// 开始下注
	@Value("${OPENNUM}")
	private String OPENNUM;
	// 开奖信息前缀
	@Value("${BEFOR}")
	private String BEFOR;
	// 开奖信息后缀
	@Value("${AFTER}")
	private String AFTER;

	private int lotteyType = 2;

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	public void run() {
		logger.info("线程启动Pc28AchieveData:startThreadThread");
		// 启动时立刻校对期号和对应开奖
		try {
			ObtainDataDto obtainData = AchieveDataUtil.getObtainInfo(PC28LOTTERYINTERFACE);
			*//************************* ** 补数据 ***************************//*
			// checkOut1();
			// 最近开奖的信息
			*//******************************************************//*
			if (obtainData != null) {
				// 当前开奖期号,当前开奖号码,当前开奖时间,
				try {
					jedisClient.set(EXPECT, obtainData.getExpect());
					jedisClient.set(OPENCODE, obtainData.getOpencode());
				} catch (Exception e) {
					e.printStackTrace();
					logger.error("redis connect error", e);
				}
			}
			// 下一期开奖时间,下一期开奖期号
			jedisClient.set(NEXTEXPECT, obtainData.getNextExpect());
			jedisClient.set(NEXTTIME, obtainData.getNextOpenTime());
			// 休眠
			logger.info("线程启动:into thread");
			ObtainDataUtils.sleep(obtainData.getNextOpenTime(), 30000);
			msgNoticeService.insertPromptNotice(STOPBET, lotteyType);
			ObtainDataUtils.sleep(obtainData.getNextOpenTime(), 0);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("before kaijiang error", e);
		}
		while (true) {
			// 休眠间隔3.5秒
			try {
				Thread.sleep(3500);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("sleep error", e);
				continue;
			}
			try {
				ObtainDataDto obtain = AchieveDataUtil.getObtainInfo(PC28LOTTERYINTERFACE);
				if (obtain == null) {
					logger.debug("get null.........");
					continue;
				}
				String expect = obtain.getExpect();
				// 从redis中查询上一期的开奖期号
				String expectRedis = jedisClient.get(EXPECT);
				logger.debug("expect in redis:{}", expectRedis);

				// 如果本次获取的开奖信息和上次相同,就结束本次循环
				if (expect.equals(expectRedis)) {
					logger.debug("get expect same as expect in redis:{}", expectRedis);
					continue;
				} else {
					// 如果本次获取的开奖信息和上次不同,就将本次的开奖信息存入数据库并跟新redis中的内容
					String opencodeOne = obtain.getOpencode();
					Date opentime = DateUtil.getDateFromString(obtain.getOpentime(), "yyyy-MM-dd HH:mm:ss"); // nowExpectInfo.getDate("opentime");

					// 查看数据库中是否有该期号的数据,如果有,就结束本次循环
					Lottery selectLotteryByExpect = lotteryDao.selectLotteryByExpect(expect);
					if (selectLotteryByExpect != null) {
						logger.debug("expect have already in database");
						continue;
					}

					// 将开奖号码做处理,转换成3位号码:"6,3,9"
					String opencode = AchieveDataUtil.numberSpilt(opencodeOne);
					if (opencode == null) {
						continue;
					}

					// 插入数据库
					Boolean insertLottery = insertLottery(expect, Integer.parseInt(expect), opencode, opentime);
					if (insertLottery == false) {
						logger.error("database insert error");
						continue;
					}

					// 当前开奖期号,当前开奖号码,当前开奖时间,
					jedisClient.set(EXPECT, expect);
					jedisClient.set(OPENCODE, opencode);
					jedisClient.set(OPENDATE, obtain.getOpentime());

					// 下一期开奖时间,下一期开奖期号
					jedisClient.set(NEXTEXPECT, obtain.getNextExpect());
					jedisClient.set(NEXTTIME, obtain.getNextOpenTime());
					logger.info("get next Expect and NextOpenTime:{}",
							obtain.getNextExpect() + " + " + obtain.getNextOpenTime());

					// 分割字符串
					String[] str = opencode.split(",");
					int amount = Integer.parseInt(str[0]) + Integer.parseInt(str[1]) + Integer.parseInt(str[2]);

					String rule = "";
					if (amount > 13 && amount % 2 != 0) {
						rule = "大单";
					} else if (amount <= 13 && amount % 2 != 0) {
						rule = "小单";
					} else if (amount >= 14 && amount % 2 == 0) {
						rule = "大双";
					} else if (amount < 14 && amount % 2 == 0) {
						rule = "小双";
					}
					// 显示开奖号码
					msgNoticeService.insertPromptNotice(
							BEFOR + expect + OPENNUM + opencode.replace(",", " ") + " " + rule + AFTER, lotteyType);
					// 开奖
					lotteryDrawService.pc28YesWinning(opencode, expect, lotteyType);
					// 显示中奖信息
					selectWinningResultsService(expect);
					// 显示开始下注
					msgNoticeService.insertPromptNotice(BEGAINBET, lotteyType);

					// 校验
					// checkOut1();

					logger.info("************************start robot betting ************************");
					// 机器人开始下注
					try {
						PlayWayThread playWayThread = new PlayWayThread();
						playWayThread.setNextTime(obtain.getNextOpenTime());
						playWayThread.setNextExpect(obtain.getNextExpect());
						playWayThread.setLotteyType(lotteyType);
						playWayThread.start();
					} catch (Exception e) {
						e.printStackTrace();
						logger.error("create thread error ", e);
					}

					// 休眠
					boolean sleep = ObtainDataUtils.sleep(obtain.getNextOpenTime(), 30000);
					if (sleep == false) {
						logger.info("格式转换异常或休眠异常,结束本次循环");
						continue;
					}
					// 显示停止下注
					msgNoticeService.insertPromptNotice(STOPBET, lotteyType);
					boolean sleepOne = ObtainDataUtils.sleep(obtain.getNextOpenTime(), 0);
					if (sleepOne == false) {
						logger.info("格式转换异常或休眠异常,结束本次循环");
						continue;
					}
				}

			} catch (Exception e) {
				e.printStackTrace();
				logger.error("开奖error:", e);
				continue;
			}

		}
	}

	// 将当前开奖信息插入数据库
	public Boolean insertLottery(String expect, int expectNum, String opencode, Date opentime) {
		Lottery lottery = new Lottery();
		lottery.setExpect(expect);
		lottery.setExpectNum(expectNum);
		lottery.setOpencode(opencode);
		lottery.setOpentime(opentime);
		lottery.setInserttime(new Date());
		lottery.setLotteyType(lotteyType);
		logger.info("插入数据库:{}", lottery);
		try {
			lotteryDao.insertLottery(lottery);
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	public void selectWinningResultsService(String expect) {
		// 根据期号查询
		List<WinningResultsDto> winningResultsList = winningResultsDao.selectWinningResultsByExpect(expect);
		for (WinningResultsDto winningResultsDto : winningResultsList) {

			// 获取中奖状态state和user_id和下注规则bettingrule
			int state = winningResultsDto.getState();
			String userId = String.valueOf(winningResultsDto.getUserId());
			String bettingrule = winningResultsDto.getBettingrule() + " " + winningResultsDto.getBettingMoney();
			double winningamount = winningResultsDto.getWinningamount();

			// 账户余额
			Account selectAccountByUserId = accountDao.selectAccountByUserId(winningResultsDto.getUserId());
			double accountFunds = selectAccountByUserId.getAccountFunds();

			// 下注人信息
			User selectId = userDao.selectId(winningResultsDto.getUserId());
			String userName = selectId.getUserName();
			String allBetNotice = "";

			String hget = jedisClient.hget(FLG, userId);
			if (hget == null) {
				List<InfoStateDto> list = new ArrayList<>();
				InfoStateDto info = new InfoStateDto();
				String msString = "";
				if (state == 0) {
					msString = "您于" + expect + "期投注的:" + bettingrule + " 未中奖.账户余额为:"
							+ String.format("%.2f", accountFunds) + "彩钻";
					info.setState(0);
					info.setMessage(msString);
				} else {
					msString = "您于" + expect + "期投注的:" + bettingrule + " 中奖啦!中奖金额为:"
							+ String.format("%.2f", winningamount) + "彩钻,账户余额为:" + String.format("%.2f", accountFunds)
							+ "彩钻";
					allBetNotice = "在" + expect + "期投注的:" + bettingrule + " 中奖啦!中奖金额为:"
							+ String.format("%.2f", winningamount) + "彩钻,账户余额为:" + String.format("%.2f", accountFunds)
							+ "彩钻";
					info.setState(1);
					info.setMessage(msString);
				}
				// if (state == 0) {
				// msString = "您于" + expect + "期投注的:" + bettingrule + "
				// 未中奖.账户余额为:"
				// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
				// info.setState(0);
				// info.setMessage(msString);
				// } else {
				// msString = "您于" + expect + "期投注的:" + bettingrule + "
				// 中奖啦!中奖金额为:"
				// + String.format("%.2f", winningamount - 0.005) + "彩钻,账户余额为:"
				// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
				// allBetNotice = "在" + expect + "期投注的:" + bettingrule + "
				// 中奖啦!中奖金额为:"
				// + String.format("%.2f", winningamount - 0.005) + "彩钻,账户余额为:"
				// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
				// info.setState(1);
				// info.setMessage(msString);
				// }
				list.add(info);
				String objectToJson = JsonUtils.objectToJson(list);
				jedisClient.hset(FLG, userId, objectToJson);
				logger.debug("set2 redis {} -- {}--{}", FLG, userId, objectToJson);
			} else {
				List<InfoStateDto> jsonToList = JsonUtils.jsonToList(hget, InfoStateDto.class);
				InfoStateDto info = new InfoStateDto();
				String msString = "";
				if (state == 0) {
					msString = "您于" + expect + "期投注的:" + bettingrule + " 未中奖.账户余额为:"
							+ String.format("%.2f", accountFunds) + "彩钻";
					info.setState(0);
					info.setMessage(msString);
				} else {
					msString = "您于" + expect + "期投注的:" + bettingrule + " 中奖啦!中奖金额为:"
							+ String.format("%.2f", winningamount) + "彩钻,账户余额为:" + String.format("%.2f", accountFunds)
							+ "彩钻";
					allBetNotice = "在" + expect + "期投注的:" + bettingrule + " 中奖啦!中奖金额为:"
							+ String.format("%.2f", winningamount) + "彩钻,账户余额为:" + String.format("%.2f", accountFunds)
							+ "彩钻";
					info.setState(1);
					info.setMessage(msString);
				}
				// if (state == 0) {
				// msString = "您于" + expect + "期投注的:" + bettingrule + "
				// 未中奖.账户余额为:"
				// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
				// info.setState(0);
				// info.setMessage(msString);
				// } else {
				// msString = "您于" + expect + "期投注的:" + bettingrule + "
				// 中奖啦!中奖金额为:"
				// + String.format("%.2f", winningamount - 0.005) + "彩钻,账户余额为:"
				// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
				// allBetNotice = "在" + expect + "期投注的:" + bettingrule + "
				// 中奖啦!中奖金额为:"
				// + String.format("%.2f", winningamount - 0.005) + "彩钻,账户余额为:"
				// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
				// info.setState(1);
				// info.setMessage(msString);
				// }
				jsonToList.add(info);
				String objectToJson = JsonUtils.objectToJson(jsonToList);
				jedisClient.hset(FLG, userId, objectToJson);
				logger.debug("set3 redis {} -- {}--{}", FLG, userId, objectToJson);
			}
			if (!allBetNotice.equals("")) {
				msgNoticeService.insertBetNotice(winningResultsDto.getUserId(), allBetNotice, lotteyType);
			}
		}

		// 游客开奖
		MessageTube messageTube = messageTubes.getPc28BetMessageTube();
		for (Entry<Integer, ArrayList<LotteryExchange>> entity : TouristData.touristPc28Win.entrySet()) {
			// MessageTube messageTube = MessageTube.getInstance();
			String userId = entity.getKey() + "";
			for (LotteryExchange one : entity.getValue()) {
				String allBetNotice = "";
				String hget = jedisClient.hget(FLG, entity.getKey() + "");
				double accountFunds = Double.parseDouble(jedisClient.hget(userId, "amount"));
				String userName = TouristData.touristInfo.get(entity.getKey()).getTouristName();
				if (hget == null) {
					List<InfoStateDto> list = new ArrayList<>();
					InfoStateDto info = new InfoStateDto();
					String msString = "";

					String betRule = one.getBettingrule() + " " + one.getBettinginfoId() + ".0";
					if (one.getWinningamount() == 0) {
						msString = "您于" + expect + "期投注的:" + betRule + " 未中奖.账户余额为:"
								+ String.format("%.2f", accountFunds) + "彩钻";
						info.setState(0);
						info.setMessage(msString);
					} else {
						msString = "您于" + expect + "期投注的:" + betRule + " 中奖啦!中奖金额为:"
								+ String.format("%.2f", one.getWinningamount()) + "彩钻,账户余额为:"
								+ String.format("%.2f", accountFunds) + "彩钻";
						allBetNotice = "在" + expect + "期投注的:" + betRule + " 中奖啦!中奖金额为:"
								+ String.format("%.2f", one.getWinningamount()) + "彩钻,账户余额为:"
								+ String.format("%.2f", accountFunds) + "彩钻";
						info.setState(1);
						info.setMessage(msString);
					}
					// if (one.getWinningamount() == 0) {
					// msString = "您于" + expect + "期投注的:" + betRule + "
					// 未中奖.账户余额为:"
					// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
					// info.setState(0);
					// info.setMessage(msString);
					// } else {
					// msString = "您于" + expect + "期投注的:" + betRule + "
					// 中奖啦!中奖金额为:"
					// + String.format("%.2f", one.getWinningamount() - 0.005) +
					// "彩钻,账户余额为:"
					// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
					// allBetNotice = "在" + expect + "期投注的:" + betRule + "
					// 中奖啦!中奖金额为:"
					// + String.format("%.2f", one.getWinningamount() - 0.005) +
					// "彩钻,账户余额为:"
					// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
					// info.setState(1);
					// info.setMessage(msString);
					// }
					list.add(info);
					String objectToJson = JsonUtils.objectToJson(list);
					jedisClient.hset(FLG, userId, objectToJson);
					logger.debug("set2 redis {} -- {}--{}", FLG, userId, objectToJson);
				} else {
					List<InfoStateDto> jsonToList = JsonUtils.jsonToList(hget, InfoStateDto.class);
					InfoStateDto info = new InfoStateDto();
					String msString = "";
					String betRule = one.getBettingrule() + " " + one.getBettinginfoId() + ".0";
					if (one.getWinningamount() == 0) {
						msString = "您于" + expect + "期投注的:" + betRule + " 未中奖.账户余额为:"
								+ String.format("%.2f", accountFunds) + "彩钻";
						info.setState(0);
						info.setMessage(msString);
					} else {
						msString = "您于" + expect + "期投注的:" + betRule + " 中奖啦!中奖金额为:"
								+ String.format("%.2f", one.getWinningamount()) + "彩钻,账户余额为:"
								+ String.format("%.2f", accountFunds) + "彩钻";
						allBetNotice = "在" + expect + "期投注的:" + betRule + " 中奖啦!中奖金额为:"
								+ String.format("%.2f", one.getWinningamount()) + "彩钻,账户余额为:"
								+ String.format("%.2f", accountFunds) + "彩钻";
						info.setState(1);
						info.setMessage(msString);
					}
					// if (one.getWinningamount() == 0) {
					// msString = "您于" + expect + "期投注的:" + betRule + "
					// 未中奖.账户余额为:"
					// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
					// info.setState(0);
					// info.setMessage(msString);
					// } else {
					// msString = "您于" + expect + "期投注的:" + betRule + "
					// 中奖啦!中奖金额为:"
					// + String.format("%.2f", one.getWinningamount() - 0.005) +
					// "彩钻,账户余额为:"
					// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
					// allBetNotice = "在" + expect + "期投注的:" + betRule + "
					// 中奖啦!中奖金额为:"
					// + String.format("%.2f", one.getWinningamount() - 0.005) +
					// "彩钻,账户余额为:"
					// + String.format("%.2f", accountFunds - 0.005) + "彩钻";
					// info.setState(1);
					// info.setMessage(msString);
					// }
					jsonToList.add(info);
					String objectToJson = JsonUtils.objectToJson(jsonToList);
					jedisClient.hset(FLG, userId, objectToJson);
					logger.debug("set3 redis {} -- {}--{}", FLG, userId, objectToJson);
				}
				if (!allBetNotice.equals("")) {
					String body = userId + "::" + userName + "::" + 0 + "::" + allBetNotice;
					Message message = new Message();
					message.setMessageBody(body);
					message.setType("0");
					message.setTimestamp(new Date().getTime());
					int push = messageTube.push(message);
					logger.debug("return index={}, {},{},{}", messageTube.getHashCode(), push, message.getType(), body);
				}
			}
		}

		// 显示内存中的中奖信息
		// 机器人
		for (Entry<Integer, ArrayList<LotteryExchange>> entity : RobotParams.robotPc28Win.entrySet()) {
			String userId = entity.getKey() + "";
			for (LotteryExchange one : entity.getValue()) {
				if (one.getWinningamount() == 0) {
					continue;
				}
				String allBetNotice = "";

				if (!RobotParams.robotinfoMap.containsKey(entity.getKey())) {
					continue;
				}
				String userName = RobotParams.robotinfoMap.get(entity.getKey()).getRobotName();

				int times = RandCodeUtil.getRandNum(3, 9);
				String robotBetInfo = AchieveDataUtil.robotDivision(one.getBettingrule()) + ".0";
				allBetNotice = "在" + expect + "期投注的:" + robotBetInfo + " 中奖啦!中奖金额为:"
						+ String.format("%.2f", one.getWinningamount()) + "彩钻,账户余额为:"
						+ String.format("%.2f", one.getWinningamount() * times) + "彩钻";
				// allBetNotice = "在" + expect + "期投注的:" + robotBetInfo + "
				// 中奖啦!中奖金额为:"
				// + String.format("%.2f", one.getWinningamount() - 0.005) +
				// "彩钻,账户余额为:"
				// + String.format("%.2f", one.getWinningamount() * times -
				// 0.005) + "彩钻";
				logger.debug("****robot pc28xianshi:{}", allBetNotice);
				if (!allBetNotice.equals("")) {
					String body = userId + "::" + userName + "::" + 0 + "::" + allBetNotice;
					Message message = new Message();
					message.setMessageBody(body);
					message.setType("0");
					message.setTimestamp(new Date().getTime());
					int push = messageTube.push(message);
					logger.debug("robot return index={}, {},{},{}", messageTube.getHashCode(), push, message.getType(),
							body);
				}
			}
		}
	}

	// 新校验数据(z)
	public void checkOut1() {
		logger.info("enter into checkout");
		String today = DateUtil.getFormatDate("yyyy-MM-dd");
		String yesterday = AchieveDataUtil.changeDate(today);
		Map<String, Object> map = new HashMap<>();
		map.put("today", today);
		map.put("yesterday", yesterday);
		// 获得校验的模板
		*//************************ 已写好方法待替换 *********************************//*
		Map<String, ObtainDataDto> checkData1 = AchieveDataUtil.GetOpencodeInfo(PC28LOTTERYINTERFACE);
		List<String> expectNum = lotteryDao.selectExpectByExpectNew(map);
		logger.info("todayExpect={}", expectNum);

		// 如果查出来的list长度等于当前期号,则无缺漏
		if (expectNum.size() == checkData1.size()) {
			return;
		} else {
			// 有缺漏
			if (expectNum.size() != 0) {
				for (String aa : expectNum) {
					checkData1.remove(aa);
				}
			}

			// 对照模板补全缺漏的期数,并开奖
			Set<String> set = checkData1.keySet();
			for (String aa : set) {
				String opencode = AchieveDataUtil.numberSpilt(checkData1.get(aa).getOpencode());
				Date opentime = null;
				try {
					opentime = DateUtil.getDateFromString(checkData1.get(aa).getOpentime(), "yyyy-MM-dd HH:mm:ss");
				} catch (ParseException e) {
					e.printStackTrace();
				}

				insertLottery(aa, Integer.parseInt(aa), opencode, opentime);
				*//***************** 待修改,默认选中pc28默认项目 2 ***************//*
				// lotteyType =2;
				lotteryDrawService.pc28YesWinning(opencode, aa, lotteyType);
			}
		}
	}*/

}
